﻿using System;
using System.IO;
using System.Security.Cryptography;
using FishServe.Core.DesignByContract;

namespace FishServe.Core.Services.UpdaterService.Common
{
	public static class Extensions
	{
		public static string ComputeFileHash(this FileInfo fileInfo, HashAlgorithm hashAlgorithm)
		{
			FileStream fileStream = null;
			byte[] hashBytes = null;
			try
			{
				fileStream = fileInfo.Open(FileMode.Open);
				hashBytes = hashAlgorithm.ComputeHash(fileStream);
			}
			catch (Exception)
			{
				Console.WriteLine(String.Format("Failed to compute hash for file '{0}'.", fileInfo.FullName));
				throw;
			}
			finally
			{
				if (fileStream != null)
					fileStream.Dispose();
			}

			return Convert.ToBase64String(hashBytes);
		}

		public static string ComputeFileHash(string fullFilePath, HashAlgorithm hashAlgorithm)
		{
			return new FileInfo(fullFilePath).ComputeFileHash(hashAlgorithm);
		}

		public static HashAlgorithm GetHashAlgorithm(string hashAlgorithmName)
		{
			HashAlgorithm algorithm = null;

			switch (hashAlgorithmName.ToUpper())
			{
				case "SHA1":
					algorithm = new SHA1Managed();
					break;
				case "SHA256":
					algorithm = new SHA256Managed();
					break;
				case "SHA384":
					algorithm = new SHA384Managed();
					break;
				case "SHA512":
					algorithm = new SHA512Managed();
					break;
				case "MD5":
					algorithm = new MD5CryptoServiceProvider();
					break;
				default:
					Console.WriteLine(String.Format("Unrecognised hash algorithm '{0}'", hashAlgorithmName));
					throw new Exception(String.Format("Unrecognised hash algorithm '{0}'", hashAlgorithmName));
			}
			return algorithm;

		}
	}

	public static class MyPath
	{
		public static string Combine(string baseDirectory, params string[] paths)
		{
			DBC.AssertNotNullOrEmpty(baseDirectory, "Expecting a baseDirectory");
			DBC.AssertNotNull(paths, "Expecting at least 1 or more paths arguments");
			foreach (var item in paths)
			{
				baseDirectory = Path.Combine(baseDirectory, item);
			}
			return baseDirectory;
		}
	}
}

